/*******************************************************************************
 *	                           bsp eep.c
 *******************************************************************************/
#include "bsp.h"
#include "pincfg.h"
#include "swiic.h"
#include "appcfg.h"

#if EEP_EN > 0
#define at_rd at24_read
#define at_wr at24_write
#endif

/*******************************************************************************
 * @brief  fun
 *******************************************************************************/
void eep_read(uint16_t addr, int16_t Len, void *pdat);
void eep_save(uint16_t addr, int16_t Len, void *pdat);

void eep_enc_save(uint16_t addr, int16_t Len, void *pdat);
void eep_enc_save(uint16_t addr, int16_t Len, void *pdat);

/*******************************************************************************
 * @brief  eep read data
 * \param[in] addr data address
 * \param[in] Len data length
 * \param[in] pdat data pointer
 * \retval: none
 *******************************************************************************/
void eep_read(uint16_t addr, int16_t Len, void *pdat)
{
#if EEP_EN > 0
	uint8_t rd1[16];
	uint8_t rd2[16];

	int16_t site = 0;

	while (site < Len)
	{
		int16_t amoumt;

		// 数量
		amoumt = Len - site;
		if (amoumt > 16)
		{
			amoumt = 16;
		}

		// 读取
		set_u8(rd1, 0x55, amoumt);
		set_u8(rd1, 0xaa, amoumt);
		at_rd(addr + site, amoumt, rd1);
		at_rd(addr + site, amoumt, rd2);

		// 比较
		if (0 == comp_u8(rd1, rd2, amoumt))
		{
			copy_u8(rd1, (uu8 *)pdat + site, amoumt);
			site += amoumt;
		}
	}
#endif
}

/*******************************************************************************
 * @brief  eep save data
 * \param[in] addr data address
 * \param[in] Len data length
 * \param[in] pdat data pointer
 * \retval: none
 *******************************************************************************/
void eep_save(uint16_t addr, int16_t Len, void *pdat)
{
#if EEP_EN > 0
	uint8_t rd[16];
	uint8_t wr[16];
	int16_t site = 0;
	uu8 err_cnt = 0;

	while (site < Len)
	{
		int16_t amoumt;

		// 数量
		amoumt = Len - site;
		if (amoumt > 16)
		{
			amoumt = 16;
		}

		copy_u8((uu8 *)pdat + site, wr, amoumt);

		// 读取
		set_u8(rd, 0x55, amoumt);

		at_wr(addr + site, amoumt, wr);
		at_rd(addr + site, amoumt, rd);

		// 比较
		if (0 == comp_u8(rd, wr, amoumt))
		{
			site += amoumt;
			err_cnt = 0;
		}
		else
		{
			err_cnt++;
			if (err_cnt > 5)
			{
				// 存储器故障
				break;
			}
		}
	}
#endif
}

#if EEP_ENCPTY_EN > 0
#include "des.h"
#endif

extern const uint16_t iap_ase_key_src[];
/*******************************************************************************
 * @brief  eep save data with des encode
 * \param[in] addr data address
 * \param[in] Len data length, must multi of 8
 * \param[in] pdat data pointer
 * \retval: none
 *******************************************************************************/
void eep_enc_save(uint16_t addr, int16_t Len, void *pdat)
{
#if EEP_ENCPTY_EN > 0

	mbedtls_des_context obj;
	int16_t cnt;
	uu8 buff[10], *src;

	if ((addr & 7) || (Len & 7))
	{
		return;
	}

	mbedtls_des_init(&obj);

	mbedtls_des_setkey_enc(&obj, (uu8 *)iap_ase_key_src);

	src = pdat;
	for (cnt = 0; cnt < Len; cnt += 8)
	{
		mbedtls_des_crypt_ecb(&obj, &src[cnt], buff);
		eep_save(addr + cnt, 8, buff);
	}

	mbedtls_des_free(&obj);

#endif
}

/*******************************************************************************
 * @brief  eep read data with des encode
 * \param[in] addr data address
 * \param[in] Len data length, must multi of 8
 * \param[in] pdat data pointer
 * \retval: none
 *******************************************************************************/
void eep_enc_read(uint16_t addr, int16_t Len, void *pdat)
{
#if EEP_ENCPTY_EN > 0

	mbedtls_des_context obj;
	int16_t cnt;
	uu8 buff[10], *des;

	if ((addr & 7) || (Len & 7))
	{
		return;
	}

	mbedtls_des_init(&obj);

	mbedtls_des_setkey_dec(&obj, (uu8 *)iap_ase_key_src);

	des = pdat;
	for (cnt = 0; cnt < Len; cnt += 8)
	{
		eep_read(addr + cnt, 8, buff);
		mbedtls_des_crypt_ecb(&obj, buff, &des[cnt]);
	}

	mbedtls_des_free(&obj);

#endif
}

/*******************************************************************************
 *                                   EOF
 *******************************************************************************/
